@using Menu = BootBlazorApp1.Model.Menu
@using BootBlazorApp1.Model
@implements IResultDialog

@EditRole?.RoleName
<TreeView TItem="Model.Menu" Items="MenuItems"
          ShowCheckbox="true"
          ShowIcon="true"
          AutoCheckChildren="true"
          AutoCheckParent="true">
</TreeView>

@code {
    private List<TreeViewItem<Menu>> MenuItems { get; set; }= new List<TreeViewItem<Menu>>();
    [Parameter]
    public int RoleId { get; set; }
    //[NotNull]Role在异步初始化中初始化，不能加NotNull
    private Role EditRole { get; set; } 
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        
        //Role在异步初始化中初始化，不能加NotNull
        EditRole = await Role.Where(x => x.Id == RoleId)
                .IncludeMany(x => x.Menus).FirstAsync();
        await RefreshMenu();
    }

    private async Task RefreshMenu()
    {
        var menus = await Menu.Select.ToListAsync();
        MenuItems.Clear();
        MenuItems.AddRange(CascadingMenu(menus,null));
    }

    private List<TreeViewItem<Menu>> CascadingMenu(List<Menu> menus, TreeViewItem<Menu>? parent) =>
        menus.Where(x => x.ParentId == (parent?.Value.Id ?? 0))
            .Select(x =>
            {
                var item = new TreeViewItem<Menu>(x){ Text = x.Title,Icon = x.Icon, IsExpand = true,Parent = parent }; 
                item.Items = CascadingMenu(menus, item);
                if (EditRole?.Menus?.Any(i => i.Id == x.Id)==true)
                {
                    item.CheckedState = CheckboxState.Checked;
                }
                return item;
            }).ToList();

    public async Task OnClose(DialogResult result)
    {
        if (result == DialogResult.Yes)
        {
            var menus = new List<Menu>();
            GetMenus(MenuItems.Where(x=>x.CheckedState!=CheckboxState.UnChecked),menus);
            EditRole.Menus = menus;
            await EditRole.SaveManyAsync(nameof(Role.Menus));
        }
    }

    private void GetMenus(IEnumerable<TreeViewItem<Menu>> items, List<Menu> menuEntities)
    {
        menuEntities.AddRange(items.Select(x=>x.Value));
        foreach (var item in items)
        {
            if (item.Items.Any(x => x.CheckedState != CheckboxState.UnChecked))
            {
                GetMenus(item.Items.Where(x=>x.CheckedState!=CheckboxState.UnChecked), menuEntities);
            }
        }
    }

}